﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Drawing;

namespace SilverlightTetris_M10CDE.Web
{
    /// <summary>
    /// Summary description for TetrisService
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    // [System.Web.Script.Services.ScriptService]
    public class TetrisService : System.Web.Services.WebService
    {
        /// <summary>
        /// Exposes encryption method functionality
        /// </summary>
        /// <param name="text"></param>
        /// <param name="sharedSecret"></param>
        /// <returns></returns>
        [WebMethod]
        public String encryptString(string text, string sharedSecret)
        {
            return Encryption.EncryptString(text, sharedSecret);
        }

        /// <summary>
        /// Return high scores
        /// </summary>
        /// <returns></returns>
        [WebMethod]
        public List<Score> getHighScores()
        {
            return ScoreFactory.getScoreTable();
        }

        /// <summary>
        /// Add new score to high scores
        /// </summary>
        /// <param name="name"></param>
        /// <param name="score"></param>
        /// <param name="lines"></param>
        /// <param name="levelReached"></param>
        /// <param name="timeTaken"></param>
        /// <param name="date"></param>
        [WebMethod]
        public void addScore(String name, String score, String lines, String levelReached, String timeTaken, String date)
        {
            ScoreFactory.addScore(name, score, lines, levelReached, timeTaken, date);
        }

        /// <summary>
        /// creates a controller object and saves its state on session variable so it can presist between service calls
        /// </summary>
        [WebMethod(EnableSession = true)]
        public void StartController()
        {
            Session["controller"] = new TetrisControl(); // assumes the default size of board
        }

        /// <summary>
        /// This method is always called before any of the controller operations get performed. this is so that the controller state can be recovered from the session 
        /// </summary>
        /// <returns></returns>
        [WebMethod(EnableSession = true)]
        private TetrisControl GetControl()
        {
            ValidateSession();
            return (TetrisControl)Session["controller"];
        }

        /// <summary>
        /// checks if a session already exists
        /// </summary>
        [WebMethod(EnableSession = true)]
        private void ValidateSession()
        {
            if (Session["controller"] == null)
                StartController();
        }

        /// <summary>
        /// after an controller operation is requests its state has to be updated onto the session
        /// </summary>
        /// <param name="controller"></param>
        [WebMethod(EnableSession = true)]
        private void SaveController(TetrisControl controller)
        {
            Session["controller"] = controller;
        }

        /// <summary>
        /// Generate a new shape
        /// </summary>
        [WebMethod(EnableSession = true)]
        public void generateShape()
        {
            TetrisControl controller = GetControl();
            controller.generateShape();
            SaveController(controller);
        }

        /// <summary>
        /// Return current shape position of all its blocks
        /// </summary>
        /// <returns></returns>
        [WebMethod(EnableSession = true)]
        public int[][] getShape()
        {
            TetrisControl controller = GetControl();
            controller.getShape();
            SaveController(controller);

            return GetControl().currentShape.ToArray();
        }

        /// <summary>
        /// Return next shape position of all its blocks
        /// </summary>
        /// <returns></returns>
        [WebMethod(EnableSession = true)]
        public int[][] getNextShape()
        {
            TetrisControl controller = GetControl();
            controller.getNextShape();
            SaveController(controller);

            return GetControl().nextShape.ToArray();
        }

        /// <summary>
        /// check if can move down
        /// </summary>
        /// <returns></returns>
        [WebMethod(EnableSession = true)]
        public Boolean gravityMove()
        {
            TetrisControl controller = GetControl();
            Boolean b = controller.gravityMove();
            SaveController(controller);

            return b;
        }

        /// <summary>
        /// move the shape left
        /// </summary>
        [WebMethod(EnableSession = true)]
        public void moveLeft()
        {
            TetrisControl controller = GetControl();
            controller.moveLeft();
            SaveController(controller);
        }

        /// <summary>
        /// move shape right
        /// </summary>
        [WebMethod(EnableSession = true)]
        public void moveRight()
        {
            TetrisControl controller = GetControl();
            controller.moveRight();
            SaveController(controller);
        }

        /// <summary>
        /// rotate shape
        /// </summary>
        [WebMethod(EnableSession = true)]
        public void rotateShape()
        {
            TetrisControl controller = GetControl();
            controller.rotateShape();
            SaveController(controller);
        }

        /// <summary>
        /// retrieve game current score
        /// </summary>
        /// <returns></returns>
        [WebMethod(EnableSession = true)]
        public int updateScore()
        {
            TetrisControl controller = GetControl();
            int score = controller.getScore();
            SaveController(controller);

            return score;
        }

        /// <summary>
        /// retrieve game current number of lines removed
        /// </summary>
        /// <returns></returns>
        [WebMethod(EnableSession = true)]
        public int updateLines()
        {
            TetrisControl controller = GetControl();
            int lines = controller.getLines();
            SaveController(controller);

            return lines;
        }

        /// <summary>
        /// get shape color
        /// </summary>
        /// <returns></returns>
        [WebMethod(EnableSession = true)]
        public String getCurrentShapeColor()
        {
            TetrisControl controller = GetControl();
            Color c = controller.currentShape.getColour();
            SaveController(controller);

            String colorName = c.Name.ToString();

            return colorName;
        }

        /// <summary>
        /// get next shape color
        /// </summary>
        /// <returns></returns>
        [WebMethod(EnableSession = true)]
        public String getNextShapeColor()
        {
            TetrisControl controller = GetControl();
            Color c = controller.nextShape.getColour();
            SaveController(controller);

            String colorName = c.Name.ToString();

            return colorName;
        }

        /// <summary>
        /// check if game has finished
        /// </summary>
        /// <returns></returns>
        [WebMethod(EnableSession = true)]
        public Boolean checkGameOver()
        {
            TetrisControl controller = GetControl();
            Boolean b = controller.getAbleToMove();
            SaveController(controller);

            return b;
        }
    }
}
